<?php

namespace app\admin\service;

use app\admin\model\Inventory as InventoryModel;
use think\facade\Db;
use app\admin\common\ServiceResponse;

class InventoryCount
{

    use ServiceResponse;


    /**
     * @describe 获取库存统计列表
     * @author: Bobo
     * @date: 2025-08-21 10:45:09
     * @param [type] @required
     * @return Renderable
     */
    public function getInventoryCountList($where, int $pageIndex, int $pageSize, $total_qty = '', $available_shipment_qty = '', $shipped_qty = '', $lock_qty = '', $actually_available_qty = '')
    {
        // "total_qty": 库存总数: 库存初始数量之和,
        // "available_shipment_qty":  库存可发货数: 库存可用数量之和,
        // "shipped_qty":  库存已发货数:库存总数-库存可发货数 - 已取消数量,
        // "lock_qty":  库存锁定数:库存锁定数量之和,
        // "actually_available_qty":  库存实际可用数: 库存可发货数-库存锁定数
        $query = Db::name('inventory')
            ->field('
            productid as product_id,
            wid as warehouse_id,
            is_futures,
            arrival_date,
            CAST(SUM(initial_qty) AS SIGNED) AS total_qty,
            CAST(SUM(available_qty) AS SIGNED) AS available_shipment_qty,
            CAST(SUM(initial_qty) - SUM(available_qty) AS SIGNED) AS shipped_qty,
            CAST(SUM(lock_qty) AS SIGNED) AS lock_qty,
            CAST(SUM(available_qty) - SUM(lock_qty) AS SIGNED) AS actually_available_qty')
            ->where(function ($query) use ($where) {
                if (count($where) > 0) {
                    $query->where($where);
                }
            })
            ->where([
                'is_del' => 0,
            ])
            ->group([
                'productid',
                'wid',
                'is_futures',
                'arrival_date'
            ])
            ->order($this->buildOrderClause($total_qty, $available_shipment_qty, $shipped_qty, $lock_qty, $actually_available_qty));

        // 先获取总数（需要单独查询避免think_count）
        $totalQuery = Db::name('inventory')
            ->where(function ($query) use ($where) {
                if (count($where) > 0) {
                    $query->where($where);
                }
            })
            ->where([
                'is_del' => 0,
            ])
            ->group([
                'productid',
                'wid',
                'is_futures',
                'arrival_date'
            ]);
        $total = $totalQuery->count();

        $data = $query
            ->page($pageIndex, $pageSize)
            ->select()
            ->toArray();

        $this->getProductName($data);
        $this->getWarehouseName($data);

        return $this->success([
            'list' => $data,
            'total' => $total
        ]);
    }

    /**
     * 构建排序子句
     * @param string $total_qty 库存总数排序
     * @param string $available_shipment_qty 库存可发货数排序
     * @param string $shipped_qty 库存已发货数排序
     * @param string $lock_qty 库存锁定数排序
     * @param string $actually_available_qty 库存实际可用数排序
     * @return array
     */
    private function buildOrderClause($total_qty = '', $available_shipment_qty = '', $shipped_qty = '', $lock_qty = '', $actually_available_qty = ''): array
    {
        // 默认排序
        $order = [
            'productid' => 'asc',
            'wid' => 'asc',
            'is_futures' => 'asc',
            'arrival_date' => 'asc'
        ];

        if ($total_qty || $available_shipment_qty || $shipped_qty || $lock_qty || $actually_available_qty) {
            $order = [];
        }
        // 处理每个排序参数
        $sortParams = [
            'total_qty' => $total_qty,
            'available_shipment_qty' => $available_shipment_qty,
            'shipped_qty' => $shipped_qty,
            'lock_qty' => $lock_qty,
            'actually_available_qty' => $actually_available_qty
        ];

        foreach ($sortParams as $field => $sortOrder) {
            if (!empty($sortOrder) && in_array($sortOrder, ['asc', 'desc'])) {
                $order[$field] = $sortOrder;
            }
        }

        return $order;
    }


    /**
     * @describe 获取已发货订单列表
     * @author: Bobo
     * @date: 2025-08-21 10:45:09
     * @param [type] @required
     * @return Renderable
     */
    public function getShippedOrderList($where, int $pageIndex, int $pageSize)
    {
        $query = Db::name('logistics_order_item')
            ->alias('loi')
            ->field('loi.order_id,loi.product_id,loi.warehouse_id,loi.number AS shipped_qty,lo.ship_date as shipped_date')
            ->join('logistics_order lo', 'loi.logistics_order_id = lo.id', 'left')
            ->where(function ($query) use ($where) {
                if (count($where) > 0) {
                    $query->where($where);
                }
            })
            ->where('lo.type', 1)
            ->where('lo.status', 1)
            ->order([
                'loi.product_id' => 'asc',
                'loi.warehouse_id' => 'asc',
            ]);
        $total = $query->count();
        $data = $query
            // ->page($pageIndex, $pageSize)
            ->select()
            ->toArray();
        $this->getProductName($data);
        $this->getWarehouseName($data);
        $this->getOrderInfo($data, ['id', 'order_no', 'order_category']);

        return $this->success([
            'list' => $data,
            'total' => $total
        ]);
    }

    /**
     * @describe 获取锁定订单列表
     * @author: Bobo
     * @date: 2025-08-21 10:45:09
     * @param [type] @required
     * @return Renderable
     */
    public function getLockOrderList($where, int $pageIndex, int $pageSize)
    {
        $query = Db::name('order_item')
            ->alias('oi')
            ->field('oi.product_id,oi.warehouse_id,oi.is_futures,oi.arrival_date,oi.pending_quantity AS lock_qty,oi.order_id')
            ->whereIn('order_id', function ($query) {
                $query->name('order')
                    ->where('is_del', 0)
                    ->whereIn('pay_status', [3, 4])
                    ->where('review_node', '<>', 1)
                    ->whereIn('status', [10, 30, 40, 100])
                    ->where('order_type', '<>', 2)
                    ->field('id');
            })
            ->where(function ($query) use ($where) {
                if (count($where) > 0) {
                    $query->where($where);
                }
            })
            ->where('oi.pending_quantity', '>', 0)
            ->where('oi.is_del', 0);
        $total = $query->count();
        $data = $query
            // ->page($pageIndex, $pageSize)
            ->select()
            ->toArray();

        $this->getProductName($data);
        $this->getWarehouseName($data);
        $this->getOrderInfo($data, ['id', 'order_no', 'pay_time', 'order_category']);
        return $this->success([
            'list' => $data,
            'total' => $total
        ]);
    }
    /**
     * @describe 获取产品名称
     * @author: Bobo
     * @date: 2025-08-21 10:45:09
     * @param [type] @required
     * @return Renderable
     */
    private function getProductName(&$list)
    {
        $productIds = array_unique(array_column($list, 'product_id'));
        $products = Db::name('product')
            ->whereIn('id', $productIds)
            ->column('cname', 'id');
        foreach ($list as &$item) {
            $item['product_name'] = $products[$item['product_id']] ?? '';
        }
    }
    /**
     * @describe 获取仓库名称
     * @author: Bobo
     * @date: 2025-08-21 10:45:09
     * @param [type] @required
     * @return Renderable
     */
    private function getWarehouseName(&$list)
    {
        $warehouseIds = array_unique(array_column($list, 'warehouse_id'));

        $warehouses = Db::name('warehouse')
            ->whereIn('id', $warehouseIds)
            ->column('name', 'id');
        foreach ($list as &$item) {
            if (strpos($item['warehouse_id'], ',') !== false) {
                $warehouseIds = explode(',', $item['warehouse_id']);
                $warehouseNames = [];
                foreach ($warehouseIds as $wid) {
                    $warehouseNames[] = $warehouses[$wid] ?? '';
                }
                $item['warehouse_name'] = implode(',', $warehouseNames);
            } else {
                $item['warehouse_name'] = $warehouses[$item['warehouse_id']] ?? '';
            }
        }
    }

    private function getOrderInfo(&$list, $fields = [])
    {
        $orderIds = array_unique(array_column($list, 'order_id'));
        $orders = Db::name('order')
            ->whereIn('id', $orderIds)
            ->column($fields, 'id');
        foreach ($list as &$item) {
            foreach ($fields as $field) {
                $item[$field] = $orders[$item['order_id']][$field] ?? '';
            }
            unset($item['order_id']);
        }
    }

    /**
     * @describe 统计库存总数变更记录
     * @author: jiang
     * @date: 2025-08-28 15:00:00
     * @param [type] @required
     * @return Renderable
     */
    public function getInventoryTotalCount($param)
    {
        // 构建查询条件
        $where = [];
        if (isset($param['product_id']) && $param['product_id']) {
            $where[] = ['productid', '=', $param['product_id']];
        }
        if (isset($param['is_futures']) && $param['is_futures'] > -1) {
            $where[] = ['is_futures', '=', $param['is_futures']];
        }
        if (isset($param['arrival_date']) && $param['arrival_date']) {
            $where[] = ['arrival_date', '=', $param['arrival_date']];
        } else {
            $where[] = ['arrival_date', 'null', ''];
        }

        // 查询库存变动记录
        $query = Db::name('inventory_change_record')
            ->alias('icr')
            ->field('icr.inventory_id, icr.business, icr.number, icr.remark, icr.creator, icr.create_time')
            ->whereIn('icr.inventory_id', function ($query) use ($where, $param) {
                $query->name('inventory')
                    ->where('is_del', 0)
                    ->where(function ($query) use ($where) {
                        if (count($where) > 0) {
                            $query->where($where);
                        }
                    })
                    ->whereRaw('FIND_IN_SET(? , wid) > 0', [$param['warehouse_id']])
                    ->field('id');
            })
            ->order([
                'icr.create_time' => 'desc',
                'icr.inventory_id' => 'desc'
            ]);

        // 获取总数
        $total = $query->count();

        $data = $query->select()->toArray();

        // 转义creator，获取操作人姓名
        if (!empty($data)) {
            $creatorIds = array_unique(array_column($data, 'creator'));
            $operators = Db::name('operator')
                ->whereIn('id', $creatorIds)
                ->column('cname', 'id');

            foreach ($data as &$item) {
                $item['creator_name'] = $operators[$item['creator']] ?? '';
            }
        }

        return $this->success([
            'list' => $data,
            'total' => $total
        ]);
    }
}
